﻿/**
* 图形设计引擎
*
*/

// Namespace
var XEngine = {
    version: '1.0.0.0',
    // 流程引擎初始化
    // @domEl:渲染流程图的目标dom元素
    init: function (domEl) {
        this._isDesignMode = false;
        if (this._domEl == null) {
            // 当前显示的图表
            this._currentDiagram = null;
        this._domEl = domEl;
            this._gi = new XGraphics();
        } else {
            throw 'XEngine has Inited!';
        }
    },

    getDomEl: function () {
        return this._domEl;
    },

    // 获取当前显示的diagram
    getCurrentDiagram : function(){
        return this._currentDiagram;
    },

    // 创建图表
    // @name:string图表的名称，唯一标识
    createDiagram: function (name) {
        if (this._currentDiagram != null
            && this._currentDiagram.getName() == name) {
            // 不能创建一个和已经在显示的图表一样名称的新图表。
            return null;
        }
        var canvas = this._gi.createCanvas();
        return new XDiagram(name, canvas);
    },

    // 显示图表
    // @diagram:XDiagram,图表对象
    showDiagram: function (diagram) {
        if (this._currentDiagram == null) {
            this._domEl.appendChild(diagram._domEl);
            this._currentDiagram = diagram;
        }else if (this._currentDiagram._name != diagram._name) {
            this._domEl.removeChild(this._currentDiagram._domEl);
            this._domEl.appendChild(diagram._domEl);
            this._currentDiagram = diagram;
        }
    },

    // 窗口坐标转换为图表中的坐标
    pointToDiagram: function (point) {
        var absoluteLeft = XUtil.getElementLeft(this._domEl);
        var absoluteTop = XUtil.getElementTop(this._domEl);
        absoluteTop -= this._domEl.scrollTop;
        absoluteLeft -= this._domEl.scrollLeft;

        return { x: point.x - absoluteLeft, y: point.y - absoluteTop };
    }
}

// 图表，在这里显示流程图的内容
function XDiagram(name, domEl) {
    this._name = name;

    this._domEl = domEl;

    // 元素列表，所有的元素都存放在这里
    this._elements = new Array();

    this.getDomEl = function () {
        return this._domEl;
    }

    // 获取名称
    // @return:string,图表的名称
    this.getName = function () {
        return this._name;
    }

    // 获取图表中所有的元素个数
    // @return:int,元素个数
    this.getLength = function () {
        return this._elements.length;
    }

    // 根据索引获取元素对象
    // @index:int,元素的索引信息
    // @return:XElement,元素对象
    this.getAt = function (index) {
        if (this._elements.length <= index) {
            return null;
        }
        return this._elements[index];
    }

    // 添加元素到图表中
    // @element:XElement,元素对象
    this.add = function (element) {
        var isExist = false;
        for (var index = 0; index < this._elements.length; index++) {
            if (this._elements[index] == element) {
                isExist = true;
                break;
            }
        }

        if (isExist == false) {
        this._elements.push(element);
            // 将元素安装到图表上
            element.install(this);
        }
    }

    // 从图表中删除元素对象
    // @element:XElement,将被删除的元素对象
    this.remove = function (element) {
        for (var index = 0; index < this._elements.length; index++) {
            if (this._elements[index] == element) {
                // 从数组中删除
                this._elements.splice(index, 1);

                // 将元素卸载掉
                element.uninstall(this);
            }
        }
    }

    // 从图表中删除元素对象
    // @index:int,将被删除的元素的索引号
    this.removeAt = function (index) {
        if (this._elements.length <= index) {
            return;
        }
        var element = this._elements[index];
        // 从数组中删除
        this._elements.splice(index, 1);
        // 将元素卸载掉
        element.uninstall(this);
    }

    // 根据坐标判断点击到了哪一个元素
    // #internal
    // #Params
    // @point:Point,x,y坐标（相对于diagram）
    // #Return:XHitResult,点击检测结果
    this.hitTest = function (point) {
        for (var index = 0; index < this._elements.length; index++) {
            if (this._elements[index].getHitTestVisible()) {
                var hitResult = this._elements[index].hitTest(point);
                if (hitResult.isHit) {
                    return hitResult;
                }
            }
        }
        return new XHitResult(false, null, null);
    }
}

// 命中测试结果
// @isHit:bool,是否命中
// @obj:XElement,命中的元素
// @offset:Point,命中点的相对偏移值
function XHitResult(isHit, obj, offset) {
    this.isHit = isHit;
    this.obj = obj;
    this.offset = offset;
}